﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using TinyLib.Input;
using TinyLib.Sprite;
using TinyLib.Entity;

using GodBuilderIdea.Tools;

namespace GodBuilderIdea
{
    public class Player : Entity
    {
      //  public EnvTile.EnvironmentType m_current_env_type = EnvTile.EnvironmentType.GRASS;
        public bool m_active = false;

        public List<Tribe> m_tribes;
        public Sprite player_gui, player_gui_glow;
        public int m_actions = 20;
        public int m_def_actions = 20;
        SpriteFont m_font;
        public Goal m_goal;
        public int m_total_tribes = 0;

        public bool m_cheat_power = false; //or what if both were told they had the power to cheat?
        public bool m_cheat_have_cheated_this_turn = false;
        public int m_cheat_tribes_to_be_deployed = 0;

        public Tribe.TribeType m_tribe_type;
        public Tools.ITool m_currentTool;
        String m_player_name = "";
        Sprite m_my_tribe, m_cheat_tribe;
        //Sprite m_selected_tribe, m_selected_dest;

        int tile_height = 10;
        int tile_width = 20;

        public Player(Game game, SpriteBatch sprite_batch, String name)
            : base(game, sprite_batch)
        {
            m_player_name = name;
            Initialize();
          //  m_currentTool = new DrawTool(m_tiles);
        }

        public override void Initialize()
        {
            base.Initialize();

            m_font = Game.Content.Load<SpriteFont>("Font");

            Texture2D tex = Game.Content.Load<Texture2D>("images/player_gui");
            player_gui = new Sprite(Spritebatch, tex, Game);

            tex = Game.Content.Load<Texture2D>("images/player_gui_glow");
            player_gui_glow = new Sprite(Spritebatch, tex, Game);

            if (m_player_name == "PlayerA") { tex = Game.Content.Load<Texture2D>("images/warm_tribe"); }
            else if (m_player_name == "PlayerB") { tex = Game.Content.Load<Texture2D>("images/cold_tribe"); }
            else { tex = Game.Content.Load<Texture2D>("images/water_tribe"); }    
            m_my_tribe = new Sprite(Spritebatch, tex, Game);

            if (m_player_name == "PlayerA") { tex = Game.Content.Load<Texture2D>("images/warm_tribe_cheat"); }
            else if (m_player_name == "PlayerB") { tex = Game.Content.Load<Texture2D>("images/cold_tribe_cheat"); }
            else { tex = Game.Content.Load<Texture2D>("images/water_tribe"); }
            m_cheat_tribe = new Sprite(Spritebatch, tex, Game);

            m_goal = new Goal(Game, Spritebatch); //randomize this in a way that no one have the same goal
            m_tribes = new List<Tribe>();
            /*
            tex = Game.Content.Load<Texture2D>("images/selected_tribe_tile_glow");
            m_selected_dest = new Sprite(Spritebatch, tex, Game);
            m_selected_tribe = new Sprite(Spritebatch, tex, Game);
            */
        }

        public override void Update(GameTime gameTime)
        {
            player_gui.position = position;
            player_gui_glow.position = position;
            base.Update(gameTime);

            m_total_tribes = 0;
            foreach (Tribe t in m_tribes)
            { m_total_tribes += t.m_amount; }

            foreach (Tribe t in m_tribes)
            { if (t.KillMe) { m_tribes.Remove(t); break; } }

            m_my_tribe.position = new Vector2(player_gui.position.X + 100, player_gui.position.Y + 20);
            m_cheat_tribe.position = m_my_tribe.position;

            m_goal.Update(gameTime);
        }

        public void NpcDoTurn(List<EnvTile> tile_list, List<Player> player_list, int world_event_index)
        {
            Random rand = new Random();
            int tile_idx = rand.Next(0, (tile_list.Count - 25));

            List<int> adjacentTileIdxs = new List<int>();
            if (!tile_list[tile_idx].left) { adjacentTileIdxs.Add(tile_idx - tile_height); }//left 
            if (!tile_list[tile_idx].right) { adjacentTileIdxs.Add(tile_idx + tile_height); }//right
            if (!tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - 1); }//up
            if (!tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + 1); }//down
            if (!tile_list[tile_idx].left && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - tile_height - 1); } //topleft
            if (!tile_list[tile_idx].right && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx + tile_height - 1); }//topright
            if (!tile_list[tile_idx].left && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx - tile_height + 1); }//botleft
            if (!tile_list[tile_idx].right && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + tile_height + 1); } //botright

            

            if (world_event_index == 1)
            {
                //filling default tiles
                
                //foreach (EnvTile tile in tile_list)
                /*
                for (int i = 0; i < 20; i++) 
                {
                    tile_list[tile_idx].m_type = EnvTile.EnvironmentType.WATER;
                    tile_list[tile_idx].m_changed_type = true;
                    tile_idx++;
                }
                */
                
                int tile_type = (int)EnvTile.EnvironmentType.WATER;
                
                int places = rand.Next(2, 4);

                for (int i = 0; i < places; i++)
                {
                    tile_idx = rand.Next(0, (tile_list.Count - 25));
                    adjacentTileIdxs = new List<int>();
                    if (!tile_list[tile_idx].left) { adjacentTileIdxs.Add(tile_idx - tile_height); }//left 
                    if (!tile_list[tile_idx].right) { adjacentTileIdxs.Add(tile_idx + tile_height); }//right
                    if (!tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - 1); }//up
                    if (!tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + 1); }//down
                    if (!tile_list[tile_idx].left && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - tile_height - 1); } //topleft
                    if (!tile_list[tile_idx].right && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx + tile_height - 1); }//topright
                    if (!tile_list[tile_idx].left && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx - tile_height + 1); }//botleft
                    if (!tile_list[tile_idx].right && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + tile_height + 1); } //botright
                    adjacentTileIdxs.Add(tile_idx);

                    foreach (int idx in adjacentTileIdxs)
                    {
                        if (tile_list[idx].m_type != EnvTile.EnvironmentType.LAVA)
                        {
                            tile_list[idx].m_type = (EnvTile.EnvironmentType)tile_type;
                            tile_list[idx].m_changed_type = true;
                        }
                    }
                }
            }
            if (world_event_index == 2)
            {
                //advancing tribe //or just fucking up for other players
                /*
                int tile_type = rand.Next(0, (int)EnvTile.EnvironmentType.SIZE);

                if ((EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.NEXT
                    || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.LAVA
                    || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.DEFAULT)
                {
                    tile_type = (int)EnvTile.EnvironmentType.WATER;
                }

                tile_idx = rand.Next(0, (tile_list.Count - 25));
                //foreach (EnvTile tile in tile_list)
                for (int i = 0; i < 20; i++)
                {
                    tile_list[tile_idx].m_type = (EnvTile.EnvironmentType)tile_type;
                    tile_list[tile_idx].m_changed_type = true;
                    tile_idx++;
                }
                */
                int tile_type = rand.Next(0, (int)EnvTile.EnvironmentType.SIZE);
                if ((EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.NEXT
                    || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.LAVA
                    || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.DEFAULT)
                { tile_type = (int)EnvTile.EnvironmentType.WATER; }

                int places = rand.Next(3, 6);

                for (int i = 0; i < places; i++)
                {
                    tile_idx = rand.Next(0, (tile_list.Count - 25));
                    adjacentTileIdxs = new List<int>();
                    if (!tile_list[tile_idx].left) { adjacentTileIdxs.Add(tile_idx - tile_height); }//left 
                    if (!tile_list[tile_idx].right) { adjacentTileIdxs.Add(tile_idx + tile_height); }//right
                    if (!tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - 1); }//up
                    if (!tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + 1); }//down
                    if (!tile_list[tile_idx].left && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - tile_height - 1); } //topleft
                    if (!tile_list[tile_idx].right && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx + tile_height - 1); }//topright
                    if (!tile_list[tile_idx].left && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx - tile_height + 1); }//botleft
                    if (!tile_list[tile_idx].right && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + tile_height + 1); } //botright
                    adjacentTileIdxs.Add(tile_idx);

                    foreach (int idx in adjacentTileIdxs)
                    {
                        if (tile_list[idx].m_type != EnvTile.EnvironmentType.LAVA)
                        {
                            tile_list[idx].m_type = (EnvTile.EnvironmentType)tile_type;
                            tile_list[idx].m_changed_type = true;
                        }
                    }
                    tile_type = rand.Next(0, (int)EnvTile.EnvironmentType.SIZE);
                    if ((EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.NEXT
                        || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.LAVA
                        || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.DEFAULT)
                    { tile_type = (int)EnvTile.EnvironmentType.WATER; }
                }
            }
            if (world_event_index == 3)
            {
                //lava and shits, evacuating tribes
                int tile_type = rand.Next(0, (int)EnvTile.EnvironmentType.SIZE);

                if ((EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.NEXT
                    || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.LAVA
                    || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.DEFAULT)
                {
                    tile_type = (int)EnvTile.EnvironmentType.WATER;
                }

                int places = rand.Next(3, 6);

                for (int i = 0; i < places; i++)
                {
                    tile_idx = rand.Next(0, (tile_list.Count - 25));
                    adjacentTileIdxs = new List<int>();
                    if (!tile_list[tile_idx].left) { adjacentTileIdxs.Add(tile_idx - tile_height); }//left 
                    if (!tile_list[tile_idx].right) { adjacentTileIdxs.Add(tile_idx + tile_height); }//right
                    if (!tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - 1); }//up
                    if (!tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + 1); }//down
                    if (!tile_list[tile_idx].left && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx - tile_height - 1); } //topleft
                    if (!tile_list[tile_idx].right && !tile_list[tile_idx].top) { adjacentTileIdxs.Add(tile_idx + tile_height - 1); }//topright
                    if (!tile_list[tile_idx].left && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx - tile_height + 1); }//botleft
                    if (!tile_list[tile_idx].right && !tile_list[tile_idx].bottom) { adjacentTileIdxs.Add(tile_idx + tile_height + 1); } //botright
                    adjacentTileIdxs.Add(tile_idx);

                    foreach (int idx in adjacentTileIdxs)
                    {
                        if (tile_list[idx].m_type != EnvTile.EnvironmentType.LAVA)
                        {
                            tile_list[idx].m_type = (EnvTile.EnvironmentType)tile_type;
                            tile_list[idx].m_changed_type = true;
                        }
                    }
                    tile_type = rand.Next(0, (int)EnvTile.EnvironmentType.SIZE);
                    if ((EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.NEXT
                        || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.LAVA
                        || (EnvTile.EnvironmentType)tile_type == EnvTile.EnvironmentType.DEFAULT)
                    { tile_type = (int)EnvTile.EnvironmentType.WATER; }
                }
            }

        }

        public override void Draw(GameTime gameTime)
        {
            if (m_active)
            {
                player_gui_glow.Draw(gameTime);
                Spritebatch.DrawString(m_font, "Actions left: " + m_actions, new Vector2(player_gui.position.X, player_gui.position.Y - 20), Color.Black);
            }
            player_gui.Draw(gameTime);

            /*
            m_selected_tribe.Draw(gameTime);
            m_selected_dest.Draw(gameTime);
            */

            foreach (Tribe t in m_tribes)
            {
                t.Draw(gameTime);
            }
            Spritebatch.DrawString(m_font, "" + m_goal.m_player_name, new Vector2(player_gui.position.X+20, player_gui.position.Y + 70), Color.Black);
            m_goal.Draw(gameTime);

            if (!m_cheat_have_cheated_this_turn)
            { m_my_tribe.Draw(gameTime); }
            else
            { m_cheat_tribe.Draw(gameTime); }
        }
    }
}
